package yfdc.douyin.download;

import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.io.IOException;

import kotlin.jvm.internal.Intrinsics;
import okhttp3.Response;
import yfdc.douyin.download.network.NetWorkCallBack;
import yfdc.douyin.download.network.Result;

public final class NetWork {
    private static final String TAG = "NetWork";
    private final Handler networkHandler;
    private final Handler mainHandler;
    private NetWork() {
        super();
        HandlerThread handlerThread = new HandlerThread("network thread");
        handlerThread.start();
        mainHandler = new Handler(Looper.getMainLooper());
        networkHandler = new NetWorkHandler(handlerThread.getLooper());
    }

    private static volatile NetWork _instance = null;

    @NotNull
    public static NetWork getInstance() {
        if (_instance == null) {
            synchronized (NetWork.class) {
                if (_instance == null) {
                    _instance = new NetWork();
                }
            }
        }
        return Utils.notNull(_instance);
    }

    public final void postHttp(@NotNull final okhttp3.Call call,
                               @NotNull final NetWorkCallBack<Response> successCallback,
                               @NotNull final NetWorkCallBack<IOException> failCallback) {
        Intrinsics.checkParameterIsNotNull(call, "call");
        Intrinsics.checkParameterIsNotNull(successCallback, "successCallback");
        Intrinsics.checkParameterIsNotNull(failCallback, "failCallback");
        networkHandler.post(() -> {
            try {
                Response res = call.execute();
                Result.<Response>callBack(true, res, successCallback);
            } catch (final java.io.IOException networkEx) {
                Result.<java.io.IOException>callBack(false, networkEx, failCallback);
            }
        });
    }

    public final void postHttp(@NotNull final okhttp3.Request request,
                               @NotNull final NetWorkCallBack<Response> successCallback,
                               @NotNull final NetWorkCallBack<IOException> failCallback) {
        Intrinsics.checkParameterIsNotNull(request, "request");
        Intrinsics.checkParameterIsNotNull(successCallback, "successCallback");
        Intrinsics.checkParameterIsNotNull(failCallback, "failCallback");
        postHttp(Utils.getGlobalClient().newCall(request), successCallback, failCallback);
    }

    private static final class NetWorkHandler extends android.os.Handler {
        private NetWorkHandler(@NotNull final android.os.Looper looper) {
            super(Utils.notNull(looper));
            Intrinsics.checkParameterIsNotNull(looper, "looper");
        }

        @Override
        public final void dispatchMessage(Message msg) {
            if (msg == null) return;
            if (msg.what == 1) {
                Object r = msg.obj;
                if (r instanceof Runnable) {
                    try {
                        ((Runnable) r).run();
                    } catch (Throwable _handled) {
                        Utils.logException(_handled, TAG);
                    }
                    return;
                }
            }
            try {
                super.dispatchMessage(msg);
            } catch (Throwable any) {
                Utils.logException(any, TAG);
            }
        }

        @Override
        public final void handleMessage(Message msg) {
            if (msg == null) return;
            try {
                super.handleMessage(msg);
            } catch (Throwable any) {
                Utils.logException(any, TAG);
            }
        }
    }

    public static void postOnNetworkThread(@Nullable final Runnable target) {
        if (target != null) {
            getInstance().networkHandler.post(target);
        }
    }

    public static void postOnMainThread(@Nullable final Runnable target){
        if (target != null) {
            getInstance().mainHandler.post(target);
        }
    }
}
